package com.scalar.chiptrack.finance.openpo.actioncommands;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.text.DecimalFormat;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.scalar.ScalarException;
import com.scalar.chiptrack.ChipTrackExtendedAction;
import com.scalar.chiptrack.commons.Address;
import com.scalar.chiptrack.finance.openpo.PurchaseOrderLineItem;
import com.scalar.chiptrack.finance.openpo.PurchaseOrderLineItemList;
import com.scalar.chiptrack.finance.openpo.ReceivingLineItem;
import com.scalar.chiptrack.finance.openpo.ReceivingLineItemList;
import com.scalar.chiptrack.finance.openpo.dao.PurchaseOrderDAO;
import com.scalar.chiptrack.finance.openpo.forms.PurchaseOrderForm;
import com.scalar.chiptrack.finance.openpo.forms.PurchaseOrderReceiptForm;
import com.scalar.chiptrack.operations.process.dao.ProductDao;
import com.scalar.chiptrack.users.ErrorReport;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;

/**
  * Author: Administrator
 * Date  : Feb 19, 2005
 * Time  : 7:03:28 PM
 */
public class PurchaseOrderConfirmCommand extends ChipTrackExtendedAction
{
    public ActionForward executeRequest( ActionMapping mapping,
                                         ActionForm form,
                                         HttpServletRequest request,
                                         HttpServletResponse response ) throws Exception
    {

        HashMap errors              = ( HashMap ) request.getAttribute( ERROR_MESSAGES );
        HashMap info                = ( HashMap ) request.getAttribute( INFO_MESSAGES );
        PurchaseOrderForm purchaseOrderForm = ( PurchaseOrderForm ) form;
		String actionForward 		= "Search";
        HttpSession mSession 		= request.getSession();
        PurchaseOrderLineItem purchaseOrderLineItem = new PurchaseOrderLineItem();
        Iterator lineItemIterator           = null;

		try
        {
            request.removeAttribute( "showReceipt" );
            
            lineItemIterator = purchaseOrderForm.getPurchaseOrderLineItemList().iterator();
            int lineItemNo = 1;
            while ( lineItemIterator.hasNext() )
            {
                purchaseOrderLineItem = ( PurchaseOrderLineItem ) lineItemIterator.next();
                if( !("".equals( purchaseOrderLineItem.getProcessName().trim())) && purchaseOrderLineItem.getProcessStepId() != -1 )
                {
                    purchaseOrderLineItem.setPartNumbersList( PurchaseOrderDAO.loadPartNumbersByVendorIdAndLocation( purchaseOrderForm.getVendor_id(), purchaseOrderLineItem.getProcessName() ) );
                    purchaseOrderLineItem.setPurchaseOrderLineItemNumber( lineItemNo++);
                }
                else
                {
                    try{
                    lineItemIterator.remove();
                    }catch( Exception e){}
                }
            }

			if( purchaseOrderForm.getPurchaseOrder_Id() == -1 && purchaseOrderForm.getOpenPurchaseOrder_Id() == -1 )
			{
				setPurchaseOrderShippingAddress( purchaseOrderForm );
			}


            addNewPOTaxState ( request, errors, purchaseOrderForm );

			PurchaseOrderReceiptForm receiptForm = preparePurchaseOrderReceipt( purchaseOrderForm );
			
			if( receiptForm != null )
			{
				mSession.setAttribute( "purchaseOrderReceiptForm", receiptForm );
				request.setAttribute( "showReceipt", "true" );
			}
			else
			{
				request.setAttribute( "showReceipt", "false" );
			}

            PurchaseOrderDAO.loadLineItemPrice( null, purchaseOrderForm.getPurchaseOrderLineItemList() );
            lineItemIterator = purchaseOrderForm.getPurchaseOrderLineItemList().iterator();
            while ( lineItemIterator.hasNext() )
            {
                purchaseOrderLineItem = ( PurchaseOrderLineItem ) lineItemIterator.next();
                if ( purchaseOrderLineItem.getUnitCost() == 0 && purchaseOrderLineItem.getProcessStepId() > 0 )
                {
                    errors.put( "Unit Cost should be valid number and first digit can not be space or zero for LineItem " + purchaseOrderLineItem.getPurchaseOrderLineItemNumber(), null );
                }
            }
            // Set Totals, Extended Price ETC
			setExtendedPriceAndTotals( purchaseOrderForm, request );
            request.setAttribute( "purchaseOrderTypesList", PurchaseOrderDAO.loadPurchaseOrderTypes() );
            request.setAttribute( "processNameList", PurchaseOrderDAO.loadProcessNames( purchaseOrderForm.getVendor_id() ) );
            request.setAttribute( "packageTypeList", PurchaseOrderDAO.loadPackageTypeList() );
            request.setAttribute( "financeReasonCodes", PurchaseOrderDAO.loadFinanceHolds() );
            request.setAttribute( "opsReasonCodes", PurchaseOrderDAO.loadOperationsHolds() );
            request.setAttribute( "poTaxes", PurchaseOrderDAO.loadPOTaxesList () );
            String searchType = request.getParameter("searchType");
            request.setAttribute( "searchType", searchType);

            if( !errors.isEmpty() )
            {
                actionForward = "NewManufacturingPO";
            }
            else
            {
                actionForward = "confirm";
            }
       	}
        catch ( Exception e )
        {
            Logger.error( ERROR_LOADING_PURCHASE_ORDER_LISTS, e );
            errors.put( ERROR_INTERNAL_SERVER_ERROR, ERROR_LOADING_PURCHASE_ORDER_LISTS );
			mSession.setAttribute( ERROR_REPORT_OBJECT, new ErrorReport( ERROR_LOADING_PURCHASE_ORDER_LISTS, e ) );
            actionForward = "Search";
        }

		request.setAttribute( ERROR_MESSAGES, errors );
		request.setAttribute( INFO_MESSAGES, info );
        saveToken( request );
		return mapping.findForward( actionForward );
    }
    
	/**
	 * @param purchaseOrderForm
	 */
	public static void setExtendedPriceAndTotals(PurchaseOrderForm purchaseOrderForm, HttpServletRequest request)
	{
		double sub_total = 0.0;
        boolean evaluateCancelledLineItems = true;
        String searchType = request.getParameter( "searchType");
        searchType = searchType == null ? "" : searchType.trim();
        if( "searchPendingPurchaseOrder".equalsIgnoreCase( searchType))
        {
            evaluateCancelledLineItems = false;
        }

		PurchaseOrderLineItemList purchaseOrderLineItemList = null;
		PurchaseOrderLineItem purchaseOrderLineItem = null;
		  
		if( purchaseOrderForm != null )
		{
			purchaseOrderLineItemList = purchaseOrderForm.getPurchaseOrderLineItemList();
            DecimalFormat formatter = new DecimalFormat("#.##");
			if( purchaseOrderLineItemList != null )
			{
				for( int i = 0; i < purchaseOrderLineItemList.size(); i++ )
				{
					purchaseOrderLineItem = (PurchaseOrderLineItem)purchaseOrderLineItemList.get(i);

/*                  exclude the lineItem's extended cost in the total, if the request has come from pending orders and if the lineItem is cancelled and the lineItem is approved */
					if( purchaseOrderLineItem.getProcessStepId() != -1 &&
                                !(  PURCHASE_ORDER_STATUS_CANCELLED.equalsIgnoreCase( purchaseOrderLineItem.getStatus())) &&
                                !(  !evaluateCancelledLineItems &&
                                    purchaseOrderLineItem.getCancel() &&
                                    (purchaseOrderLineItem.getFinanceHold() == 0) &&
                                    (purchaseOrderLineItem.getOperationsHold() == 0 ) )  )
					{
						try
						{
                            String output = formatter.format(purchaseOrderLineItem.getUnitCost() * purchaseOrderLineItem.getRequestedQuantity());
							purchaseOrderLineItem.setExtendedCost(  Double.parseDouble( output) );
							sub_total = sub_total + purchaseOrderLineItem.getExtendedCost();

						}
						catch( Exception e )
						{
							purchaseOrderLineItem.setExtendedCost( 0.0 );
						}
					}
				}
				purchaseOrderForm.setSubTotal( Double.parseDouble( formatter.format( sub_total)) );
			}
			
            try
			{
                String poTaxType = purchaseOrderForm.getPoTaxType();
                double subTotal  = purchaseOrderForm.getSubTotal();
                double tax = PurchaseOrderDAO.getTaxValue( poTaxType );
                purchaseOrderForm.setTax(  Double.parseDouble( formatter.format( (tax*subTotal)/100 ) ) );
			}
			catch( Exception e )
			{
				purchaseOrderForm.setTax( 0.0 );
			}

            try
            {
                String output = formatter.format( purchaseOrderForm.getSubTotal() + purchaseOrderForm.getFreight() + purchaseOrderForm.getTax() + purchaseOrderForm.getMiscellaneous() - purchaseOrderForm.getTradeDiscount() );
                purchaseOrderForm.setTotal( Double.parseDouble( output) );       
            }
            catch( Exception e )
            {
                purchaseOrderForm.setTotal( 0.0 );
            }
		}
	}

	/**
	 * @param purchaseOrderForm
	 */
	private void setPurchaseOrderShippingAddress( PurchaseOrderForm purchaseOrderForm) throws ScalarException
	{
		ArrayList addressList 	= PurchaseOrderDAO.loadVendorShippingAddresses( purchaseOrderForm.getVendor_id() );
		Address address 		= null;
		String contactPersonAddress_Id 	= purchaseOrderForm.getContactPerson();
		
		if( contactPersonAddress_Id != null )
		{
			for( int i = 0; i < addressList.size(); i++ )
			{
				address = (Address)addressList.get( i );
				if( ( address.getContactPersonAddressId()+"" ).equalsIgnoreCase( contactPersonAddress_Id ) )
				{
					purchaseOrderForm.setShippingAddress( address );
				}
			}
		}
	}
	
	public static PurchaseOrderReceiptForm preparePurchaseOrderReceipt( PurchaseOrderForm purchaseOrderForm )throws ScalarException
	{
		PurchaseOrderReceiptForm receiptForm = null;
		PurchaseOrderLineItemList purchaseOrderLineItemList = null;
		PurchaseOrderLineItem purchaseOrderLineItem = null;
		ReceivingLineItemList receiptLineItemList = new ReceivingLineItemList();
		ReceivingLineItem receivingLineItem = null;
		double subTotal = 0.0;
		double extendedCost = 0.0;
		
		boolean receipt = false; 
		
		if( purchaseOrderForm != null )
		{
			purchaseOrderLineItemList = purchaseOrderForm.getPurchaseOrderLineItemList();
			
			if( purchaseOrderLineItemList != null && purchaseOrderLineItemList.isEmpty() == false )
			{
				for( int i = 0; i < purchaseOrderLineItemList.size(); i++ )
				{
					purchaseOrderLineItem = ( PurchaseOrderLineItem )purchaseOrderLineItemList.get( i );
					if( purchaseOrderLineItem.getShippedQty() > 0 )
					{
						receipt = true;
						break; 
					}
				}
			}
			
			if( receipt )
			{
				receiptForm = new PurchaseOrderReceiptForm();
				
				// Set the Receipt Information
				receiptForm.setReceipt_id( -1 );
				receiptForm.setReceipt_Number( PurchaseOrderDAO.loadAutomatedReceiptNo() );
				receiptForm.setPurchaseOrder_Id( purchaseOrderForm.getPurchaseOrder_Id() );
				receiptForm.setPurchaseOrderNumber( purchaseOrderForm.getPurchaseOrderNumber() );
				receiptForm.setVendor_id( purchaseOrderForm.getVendor_id() );
				receiptForm.setReceiptDate( purchaseOrderForm.getPurchaseOrderDate() );
				receiptForm.setStatus( "New" );
				receiptForm.setSub_total( 0.0 );
				receiptForm.setTrade_Discount( 0.0 );
				receiptForm.setFrieght( 0.0 );
				receiptForm.setMiscellaneous( 0.0 );
				receiptForm.setTax( 0.0 );
				receiptForm.setTotal( 0.0 );
				receiptForm.setVendorName( purchaseOrderForm.getVendorName() );
                receiptForm.setVendorDocNumber( purchaseOrderForm.getVendorQuoteNumber() );
                receiptForm.setPoTaxType( purchaseOrderForm.getPoTaxType() );

				// Set the Line Item Details
				for( int i = 0; i < purchaseOrderLineItemList.size(); i++ )
				{
					purchaseOrderLineItem = ( PurchaseOrderLineItem )purchaseOrderLineItemList.get( i );
					if( purchaseOrderLineItem.getShippedQty() > 0 )
					{
						receivingLineItem = new ReceivingLineItem();
						receivingLineItem.setRecevingLineItem_Id( -1 );
						receivingLineItem.setPurchaseOrderLineItem_Id( purchaseOrderLineItem.getPurchaseOrderLineItem_Id() );
						receivingLineItem.setPurchaseOrderLineItemNumber( purchaseOrderLineItem.getPurchaseOrderLineItemNumber() );
						receivingLineItem.setProcessName( purchaseOrderLineItem.getProcessName() );
						receivingLineItem.setPackageType( purchaseOrderLineItem.getPackageType() );
						receivingLineItem.setProcessStepId( purchaseOrderLineItem.getProcessStepId() ) ;
						receivingLineItem.setDescription( purchaseOrderLineItem.getDescription() );
						receivingLineItem.setRequestedDate( purchaseOrderLineItem.getRequestedDate() );
						receivingLineItem.setRequestedQuantity( purchaseOrderLineItem.getRequestedQuantity() );
						receivingLineItem.setPreviouslyShipppedQty( purchaseOrderLineItem.getPreviouslyShipppedQty() );
						receivingLineItem.setReceivedDate( purchaseOrderForm.getPurchaseOrderDate() );
						receivingLineItem.setUnitCost( purchaseOrderLineItem.getUnitCost() );
						receivingLineItem.setShippedQty( purchaseOrderLineItem.getShippedQty() );
						
						try
						{
							extendedCost = purchaseOrderLineItem.getUnitCost() * purchaseOrderLineItem.getShippedQty();
						}
						catch( Exception e )
						{
							extendedCost = 0.0;
						}
						
						receivingLineItem.setExtendedCost( extendedCost );
						receivingLineItem.setInvoiced_Qty( purchaseOrderLineItem.getShippedQty() );
						receivingLineItem.setPartNumber( ProductDao.getProductNameByProcessStep_Id( purchaseOrderLineItem.getProcessStepId() ) );
						receivingLineItem.setSelected( true );
						
						receivingLineItem.setPurchaseOrderLineItemLotDataEntryList( purchaseOrderLineItem.getPurchaseOrderLineItemLotDataEntryList() );
						
						receiptLineItemList.add( receivingLineItem );					 
					}
				}
				
				receiptForm.setReceivingLineItemList( receiptLineItemList );
				
				// Set the Sub Total and Total 
				
				for( int i = 0; i < receiptLineItemList.size(); i++ )
				{
					receivingLineItem = (ReceivingLineItem)receiptLineItemList.get( i );
					try
					{
						subTotal = subTotal + receivingLineItem.getExtendedCost();
					}
					catch( Exception e){}
				}
				
				receiptForm.setSub_total( subTotal );
                if ( receiptForm.getPoTaxType() != null && receiptForm.getPoTaxType().length() > 0 )
                {
                    receiptForm.setTax( ( subTotal * PurchaseOrderDAO.getTaxValue( receiptForm.getPoTaxType() ) ) / 100 );
                }
				receiptForm.setTotal( subTotal + receiptForm.getTax() );
			}
		}
		return receiptForm;
	}
    private void addNewPOTaxState ( HttpServletRequest request, HashMap errors, PurchaseOrderForm subform )
    {
        String state = null;
        String value = null;
        String newPOState = null;
        String newPOTax = null;
        boolean checkstate = false;

        try
        {
            state = request.getParameter ( "newPOState" );
            value = request.getParameter ( "newPOTax" );

            String poTaxType = request.getParameter ( "poTaxType" );

            if ( "-1".equals ( poTaxType ) )
            {
                if ( state != null )
                {
                    state = state.trim ();
                }
                checkstate = PurchaseOrderDAO.doesPOTaxStateExist ( null, state );
                if ( checkstate == false )
                {
                    if ( value != null )
                    {
                        value = StringUtils.formatAmount( Float.parseFloat(value) );
                    }
                    if ( ( state != null && state.length () > 0 ) && ( value != null && value.length () > 0 ) )
                    {
                        newPOState = state.trim ();
                        newPOTax = value.trim ();
                        PurchaseOrderDAO.savePOTax( newPOState, newPOTax );
                        ArrayList poStatesList = PurchaseOrderDAO.loadPOTaxesList();
                        poStatesList.add ( new org.apache.struts.util.LabelValueBean ( state + " - " + value, state ) );
                        request.setAttribute ( "poTaxes", poStatesList );
                        subform.setPoTaxType ( state );
                    }
                }
                else
                {
                    errors.put ( "The State '" + state + "' already exists", null );
                    request.setAttribute ( "otherstateadded", "false" );
                    request.setAttribute ( "newPOState", state );
                    request.setAttribute ( "newPOTax", value );
                }
            }
        }//try
        catch ( Exception e )
        {
            errors.put ( ERROR_INTERNAL_SERVER_ERROR, ERROR_IN_SAVING_NEW_PO_TAX_STATE );
            errors.put ( ERROR_MESSAGE_CONTACT_SYS_ADMN, null );
        }
        request.setAttribute ( "Errors", errors );

    }//end of method addNewPOTaxState

}
